package pers.ree.demo.base;

public class InnerClassDemo {

    private int x;

    private int y;


    public static void main(String[] args) {
        String s1 = "abc";
//        s1 = "bcd"; // 如果修改s1的值，也会导致下面的匿名内部类中s1变量编译报错

        InnerInterface1 iif1 = new InnerInterface1() {
            // jdk8以前，接口的实现方法加@Override会编译报错
            @Override
            public void print(String s) {
                // jdk6以前，如果s1没有加final，此处会编译报错
                // jdk8开始，s1可以不加final，但是不能修改，如 s1="abc";
                System.out.println(s1 + s);
//                s1 = "abc";
            }
        };

        iif1.print("!");

        InnerClassDemo innerClassDemo = new InnerClassDemo();
        innerClassDemo.modifyVar();
        System.out.println("innerClassDemo.y=" + innerClassDemo.y);
    }

    public void modifyVar() {
        InnerInterface1 iif1 = new InnerInterface1() {
            // jdk6以前，接口的实现方法加@Override会编译报错
            @Override
            public void print(String s) {
                System.out.println("x+y=" + (x + y));
            }
        };
        iif1.print("bcd");

        int localVar1 = 1;
        int localVar2 = x; // 这里除了可以赋予常量（如：1）还允许赋予变量（如：x）
        // localVar2 = 3会编译报错，但是localVar2 = x;x=1;x=2都不会报错
        // 但是下面的x=1;x=2和MethodInnerClass之后的x=3都不会对MethodInnerClass.getLocalVar1中localVar2的值产生影响，
        // 因为int localVar2 = x时就为localVar2拷贝了x的默认初始值0并保存在内部类的常量池中。
        // 如果在private int x时为x赋值，则localVar2等于该值
//        localVar2 = 3;
//        x = 1;
//        x = 2;

        class MethodInnerClass {
            public int getLocalVar1() {
                // jdk8开始，内部类（含匿名内部类）使用的局部变量可以不加final
                System.out.println("localVar2=" + localVar2);
                return localVar1;
            }
        }

        // 这里也不会导致MethodInnerClass.getLocalVar1使用localVar2的地方编译报错
//        x = 3;

        MethodInnerClass methodInnerClass = new MethodInnerClass();
        System.out.println("methodInnerClass.getLocalVar1="+methodInnerClass.getLocalVar1());

        // 内部接口不能定义在方法中
//        interface MethodInnerInterface {
//
//        }
    }

    interface InnerInterface1 {
        void print(String s);
    }

    class InnerClass1 {
        int z = 100;

        public int add() {
            return x + y + z;
        }
    }
}
